package com.gecba.modular.jpa.service.impl;

import cn.hutool.core.lang.Assert;
import com.gecba.modular.jpa.repository.BaseRepository;
import com.gecba.modular.jpa.service.IService;
import com.gecba.modular.jpa.utils.ReflectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.data.jpa.domain.Specification;

import javax.persistence.criteria.Predicate;
import java.io.Serializable;
import java.lang.reflect.Field;
import java.lang.reflect.Type;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Objects;

/**
 * @author ChenBo
 * @className ServiceImpl
 * @date 2021/9/8
 */
@SuppressWarnings("unchecked")
public class ServiceImpl<R extends BaseRepository<T,ID>,T,ID extends Serializable> implements IService<T,ID> {

    @Autowired
    protected R baseRepository;

    /**
     * 获取对应 entity 的 BaseMapper
     *
     * @return BaseMapper
     */
    @Override
    public R getBaseRepository() {
        return baseRepository;
    }

    protected Class<T> entityClass = currentModelClass();

    protected Class<T> repositoryClass = currentRepositoryClassClass();

    @Override
    public Class<T> getEntityClass() {
        return entityClass;
    }

    protected Class<T> currentRepositoryClassClass() {
        return (Class<T>) ReflectionUtils.getSuperClassGenericType(getClass(), 0);
    }

    protected Class<T> currentModelClass() {
        return (Class<T>) ReflectionUtils.getSuperClassGenericType(getClass(), 1);
    }


    /**
     * 根据字符串获取排序规则
     * @param sort
     * @return
     */
    protected Sort.Direction getSortDirection(String sort) {
        if(StringUtils.isNotBlank(sort)){
            sort = sort.toLowerCase();
            switch (sort){
                case "asc":
                    return Sort.Direction.ASC;
                case "desc":
                default:
                    return Sort.Direction.DESC;
            }
        }
        return Sort.Direction.DESC;
    }

}
